<?php

namespace Biz\service\brand;

use Biz\model\brand\Brand as mBrand;
use Biz\model\brand\Content;
use Biz\model\brandAccount\BrandAccountInfo;
use Biz\model\brandActivity\BrandActivityBasic;
use Biz\model\brandDecoration\BrandCard;
use Biz\model\brandRights\MBrandLevelGrowth;
use Biz\model\brandRights\MBrandLevelGrowthValue;
use Biz\model\GoodsTestActivity\FineGoodsModel;
use Biz\service\BrandRemind\BrandLevelRemind as sBrandLevelRemind;
use Biz\service\BrandRights\BrandLevelRightsService;
use Doraemon\model\MemberExtendInfo;
use Doraemon\model\Photos;
use Doraemon\service\Task\Task;
use Doraemon\tools\Log;

/**
 * @method static levelTaskPublish(int $uid, int $brandId = 0, bool $add = true)
 * @method static levelTaskClaim(int $uid, int $brandId = 0, bool $add = true)
 * @method static levelTaskJoin(int $uid, int $brandId = 0, bool $add = true)
 * @method static dailyTaskPublish(int $uid, int $brandId = 0, bool $add = true)
 * @method static dailyTaskClaim(int $uid, int $brandId = 0, bool $add = true)
 * @method static dailyTaskClaimWiki(int $uid, int $brandId = 0, bool $add = true)
 * @method static dailyTaskFeatured(int $uid, int $brandId = 0, bool $add = true)
 * @method static dailyTaskLiked(int $uid, int $brandId = 0, bool $add = true)
 * @method static dailyTaskReviewed(int $uid, int $brandId = 0, bool $add = true)
 * @method static primaryTaskDone(int $uid, int $brandId = 0, bool $add = true)
 *
 */
class BrandGrowth
{

    const TASK_ID_LOGO = 215;
    const TASK_ID_SLOGAN = 216;
    const TASK_ID_INTRO = 217;
    const TASK_ID_CARD = 218;
    const TASK_ID_COVER_IMG = 219;
    const TASK_ID_CARD_BANNER = 220;
    public static $remainBrandLevel = 0;
    private $do;
    private $uid;
    private $brandId;
    private $level;
    private $taskId;
    private $work;
    private $growth;
    private $brandInfo;
    private $increase = true;

    /**
     * @param mixed $work
     */
    protected function setWork($work): BrandGrowth
    {
        $this->work = $work;
        return $this;
    }

    private function __construct($uid, $brandId = 0)
    {
        $this->uid = $uid;
        $this->brandId = $brandId;
    }

    protected function brandInfo(): BrandGrowth
    {
        $this->brandInfo = $this->uid > 0 ? mBrand::getBrandInfoByUid($this->uid) : mBrand::getInfo($this->brandId);
        $this->brandId = $this->brandInfo['id'] ?? 0;
        $this->uid = $this->brandInfo['uid'] ?? 0;
        $this->level = $this->brandInfo['level'] ?? 0;
        $this->growth = $this->brandInfo['growth_value'] ?? 0;
        $status = $this->brandInfo['status'] ?? 0;
        $this->do = !$this->increase || ($status == mBrand::STATUS_USING);
        if (self::$remainBrandLevel) $this->level = self::$remainBrandLevel;
        return $this;
    }

    public static function getInstance($uid, $brandId = 0): BrandGrowth
    {
        return new self($uid, $brandId);
    }

    protected function increaseAble($bool): BrandGrowth
    {
        $this->increase = $bool;
        return $this;
    }

    public static function lostNotice($brand_ids, $brand_infos = [], $dayCount = 7)
    {
        if (is_scalar($brand_ids)) $brand_ids = [$brand_ids];

        //7内未完成任意任务
        $undo = self::undo($brand_ids, $dayCount);
        if ($undo) $undo = array_combine($undo, $undo);
        $remind = new sBrandLevelRemind();

        foreach ($brand_ids as $brand_id) {
            $brand_info = $brand_infos[$brand_id] ?? [];
            if (empty($brand_info)) continue;
            if (!isset($undo[$brand_id])) continue;
            $remind->handle(sBrandLevelRemind::REMIND_SCENE_NOT_FINISH_TASK_6DAYS, $brand_info['uid']);
        }




    }

    /**
     * 成长值扣除下限：100
     * 付费品牌扣减规则
     * * 7内未完成任意任务， 则第8日起每日扣除5点成长值
     * 到期品牌扣减规则
     * * 账号过期后的前30天，成长值每日扣除5点
     * * 账号过期的30天后，成长值每日扣除200点
    */
    public static function lost($brand_ids, $brand_infos = [], $dayCount = 7)
    {
        if (is_scalar($brand_ids)) $brand_ids = [$brand_ids];

        //7内未完成任意任务
        $undo = self::undo($brand_ids, $dayCount);
        if ($undo) $undo = array_combine($undo, $undo);

        //账号过期
        $where = [
            'type' => BrandAccountInfo::ACCOUNT_TYPE_BRAND,
            'account_status[!]' => BrandAccountInfo::ACCOUNT_STATUS_DEL,
            'brand_id' => $brand_ids,
        ];
        $accountList = BrandAccountInfo::getAllByWhere($where, ['brand_id', 'in_end_time']);
        $last30Days = date("Y-m-d", strtotime("-30 days"));
        $now = date("Y-m-d");
        $decreaseExpireBrand = [];
        foreach ($accountList as $item) {
            $temp_brand_id = $item['brand_id'];
            if ($item['in_end_time'] < $last30Days) {
                $decreaseExpireBrand[] = $temp_brand_id;
                unset($undo[$temp_brand_id]);
                continue;
            }
            if ($item['in_end_time'] < $now) {
                $undo[$temp_brand_id] = $temp_brand_id;
            }
        }

        $decrease = -5;
        $decreaseExpire = -200;
        self::lostOperate($undo, $brand_infos, $decrease);
        self::lostOperate($decreaseExpireBrand, $brand_infos, $decreaseExpire);
    }

    public static function lostOperate($brand_ids, $brand_infos, $decrease)
    {
        $limit = 100;
        foreach ($brand_ids as $brand_id) {
            $brand_info = $brand_infos[$brand_id] ?? [];
            if (empty($brand_info)) continue;
            $initialLevel = $brand_info['level'];
            $initialGrowth = $brand_info['growth_value'];
            if ($initialGrowth <= $limit) continue;
            if (($initialGrowth + $decrease) < $limit) {
                $decrease = $limit - $initialGrowth;
                $initialGrowth = $limit;
            } else {
                $initialGrowth += $decrease;
            }
            $level = BrandGrowth::growthLevel($initialGrowth);
            mBrand::incrGrowth($brand_id, $decrease, $level);
            BrandGrowth::growthLog($brand_id, $brand_info['uid'], $initialLevel, $level, 0, 0, $decrease);
            if ($initialLevel > $level) {
                //降级逻辑
                BrandLevelRightsService::afterLevelDown($brand_id, $level, $initialLevel);
                //执行存量任务
                BrandGrowth::upgrade($brand_id, $brand_info['uid'], $level, false);
            }
        }
    }

    public static function undo($brand_id, $dayCount = 7)
    {
        $date = date("Y-m-d", strtotime("-$dayCount days"));
        $list = MBrandLevelGrowth::select('brand_id', ['brand_id' => $brand_id, 'growth_date[>]' => $date, 'growth_value[>]' => 0, 'GROUP' => 'brand_id']);
        return is_scalar($brand_id) ? !in_array($brand_id, $list) : array_diff($brand_id, $list);
    }

    public static function upgrade($brand_id, $uid, $level = 0, $pure = true)
    {
        if (!$pure) self::$remainBrandLevel = $level;
        //当前等级任务的id
        list($publish, $claim, $join) = BrandGrowth::levelTaskConfig($level);
        $levelGroupId = BrandGrowth::levelGroupId($level);
        //查询当前任务的完成情况
        $rs = Task::getTaskListByGroupId($uid, $levelGroupId);
        $taskList = $rs[$levelGroupId]['task_list'] ?? [];
        $undo = [];
        $max = [];
        foreach ($taskList as $task) {
            $undo[$task['id']] = $task['operated_num'];
            $max[$task['id']] = $task['operate_num'];
        }
        $publishDone = $undo[$publish] ?? 0;
        $claimDone = $undo[$claim] ?? 0;
        $joinDone = $undo[$join] ?? 0;
        $publishMax = $max[$publish] ?? 0;
        $claimMax = $max[$claim] ?? 0;
        $joinMax = $max[$join] ?? 0;

        //存量情况
        $info = MBrandLevelGrowthValue::dataSelectInfo(['brand_id' => $brand_id]);
        $claim = $info['claim'] ?? 0;
        $publish = $info['publish'] ?? 0;
        $join = $info['join'] ?? 0;
        $claim -= $claimDone;
        $publish -= $publishDone;
        $join -= $joinDone;
        //执行最小数
        $claim = min($claim, $claimMax);
        $publish = min($publish, $publishMax);
        $join = min($join, $joinMax);

+        Log::info('品牌升级自动完成任务['. $level .']', compact('pure', 'brand_id', 'claim', 'publish', 'join'));

        for ($i = 0; $i < $claim; $i++) {
            self::levelTaskClaim(0, $brand_id, false);
        }
        for ($i = 0; $i < $publish; $i++) {
            self::levelTaskPublish(0, $brand_id, false);
        }
        for ($i = 0; $i < $join; $i++) {
            self::levelTaskJoin(0, $brand_id, false);
        }
    }

    public static function todayGrowth($brand_id): array
    {
        $list = MBrandLevelGrowth::dataSelect(['brand_id' => $brand_id, 'status' => 1, 'growth_date' => date("Ymd")]);
        $map = [];
        foreach ($list as $v) {
            $map[$v['group_id']] = isset($map[$v['group_id']]) ? $map[$v['group_id']] + $v['growth_value'] : $v['growth_value'];
        }
        return $map;
    }

    //成长值获取日志
    public static function growthLog($brand_id, $uid, $level, $growth_level, $group_id, $task_id, $growth_value, $addtime = null, $growth_date = null)

    {
        if (is_null($addtime)) $addtime = date("Y-m-d H:i:s");
        if (is_null($growth_date)) $growth_date = date("Ymd");
        $data = compact('brand_id', 'uid', 'level', 'growth_level', 'group_id', 'growth_value', 'task_id', 'addtime', 'growth_date');
        MBrandLevelGrowth::dataInsert($data);
    }

    /**
     * 根据分数获取当前等级
     */
    public static function growthLevel($score): int
    {
        $level = 0;
        if ($score > 68049) {
            $level = 7;
        } elseif ($score > 38999) {
            $level = 6;
        } elseif ($score > 20349) {
            $level = 5;
        } elseif ($score > 9849) {
            $level = 4;
        } elseif ($score > 3899) {
            $level = 3;
        } elseif ($score > 1249) {
            $level = 2;
        } elseif ($score > 99) {
            $level = 1;
        }
        return $level;
    }

    public static function initBrandTask($uid, $brandId = 0)
    {
        return self::getInstance($uid, $brandId)->brandInfo()->initTask();
    }

    /**
     * 升级后初始化任务状态
    */
    protected function initTask()
    {
        //查询认领内容总数
        $claim = Content::count(['wiki_num[>]' => 0, 'brand_id' => $this->brandId, 'claim_content_status' => 1]);
        //发布篇精选内容
        $publish = Photos::count(['uid' => $this->uid, 'quality' => [Photos::QUALITY_FEATURED, Photos::QUALITY_HIGH]]);
        //参与营销活动
        $join = (int)\Biz\model\brandActivity\BlindBoxActivity::count(['brand_id' => $this->brandId, 'activity_state' => \Biz\model\brandActivity\BlindBoxActivity::ACTIVITY_STATE_PASS]);
        $join += (int)FineGoodsModel::count(['brand_id' => $this->brandId, 'activity_state' => FineGoodsModel::STATE_PASS]);
        $join += (int)BrandActivityBasic::count(['brand_id' => $this->brandId, 'activity_state' => BrandActivityBasic::ACTIVITY_STATE_NORMAL, 'activity_type' => BrandActivityBasic::ACTIVITY_TYPE_NEW_PRODUCT]);

        $info = MBrandLevelGrowthValue::dataSelectInfo(['brand_id' => $this->brandId]);
        $data= [
            'claim' => $claim,
            'publish' => $publish,
            'join' => $join,
        ];
        if (!$info) {
            $data += [
                'brand_id' => $this->brandId,
                'claim_remain' => $claim,
                'publish_remain' => $publish,
                'join_remain' => $join,
            ];
            return MBrandLevelGrowthValue::dataInsert($data);
        }
        return MBrandLevelGrowthValue::dataUpdate($data, ['id' => $info['id']]);
    }

    protected function primaryTask(): BrandGrowth
    {
        if ($this->level != 0) return $this;
        //查询对应的填写信息,如果已经填写,完成任务id
        $logo = $this->brandInfo['logo'] ?? '';
        $discription = $this->brandInfo['discription'] ?? '';
        $detail = $this->brandInfo['detail'] ?? '';
        $card_image = $this->brandInfo['card_image'] ?? '';
        if ($logo) $this->taskId[] = self::TASK_ID_LOGO; //上传品牌Logo
        if ($discription) $this->taskId[] = self::TASK_ID_SLOGAN; //填写品牌语/Slogan
        if ($detail) $this->taskId[] = self::TASK_ID_INTRO; //填写品牌简介
        if ($card_image) $this->taskId[] = self::TASK_ID_CARD; //添加品牌卡片
        $extendInfo = MemberExtendInfo::getInfo($this->uid);
        $cover_img = $extendInfo['cover_img'] ?? '';
        if ($cover_img) $this->taskId[] = self::TASK_ID_COVER_IMG; //添加主页头图
        $cardList = BrandCard::getBrandCards($this->brandId);
        if ($cardList) {
            foreach ($cardList as $card) {
                if ($card['card_type'] == BrandCard::CARD_TYPE_BANNER) {
                    $this->taskId[] = self::TASK_ID_CARD_BANNER; //添加≥1个轮播banner
                    break;
                }
            }
        }
        return $this;
    }

    public static function levelGroupId($level): int
    {
        $groupId = 0;
        if ($level < 2) {
            $groupId = 64;
        } elseif ($level < 3) {
            $groupId = 65;
        } elseif ($level < 4) {
            $groupId = 66;
        } elseif ($level < 5) {
            $groupId = 67;
        } elseif ($level < 6) {
            $groupId = 68;
        } elseif ($level < 7) {
            $groupId = 69;
        }
        return $groupId;
    }

    protected static function levelTaskConfig($level): array
    {
        $publish = 0;
        $claim = 0;
        $join = 0;
        if ($level < 2) {
            $publish = 227;
            $claim = 228;
            $join = 229;
        } elseif ($level < 3) {
            $publish = 230;
            $claim = 231;
            $join = 232;
        } elseif ($level < 4) {
            $publish = 233;
            $claim = 234;
            $join = 235;
        } elseif ($level < 5) {
            $publish = 236;
            $claim = 237;
            $join = 238;
        } elseif ($level < 6) {
            $publish = 239;
            $claim = 240;
            $join = 241;
        } elseif ($level < 7) {
            $publish = 242;
            $claim = 243;
            $join = 244;
        }
        return [$publish, $claim, $join];
    }

    protected function levelTask(): BrandGrowth
    {
        //不同等级,走不同的任务
        list($publish, $claim, $join) = self::levelTaskConfig($this->level);
        $this->taskId = ${$this->work} ?? 0;
        if ($this->taskId && $this->increase) {
            if (MBrandLevelGrowthValue::count(['brand_id' => $this->brandId])) {
                MBrandLevelGrowthValue::dataUpdate(["{$this->work}[+]" => 1], ['brand_id' => $this->brandId]);
            } else {
                MBrandLevelGrowthValue::dataInsert(['brand_id' => $this->brandId, $this->work => 1]);
            }

        }
        return $this;
    }

    protected function dailyTask(): BrandGrowth
    {
        $map = [
            'publish' => 221, //每日任务.发布内容
            'claim' => 222, //每日任务.认领住友内容
            'claimWiki' => 223, //每日任务.为住友内容关联商品
            'featured' => 224, //每日任务.设置精选内容
            'liked' => 225, //每日任务.与住友点赞互动
            'reviewed' => 226, //每日任务.与住友评论互动
        ];
        $this->taskId = $map[$this->work] ?? 0;
        return $this;
    }

    protected function run($method = 'dailyTask')
    {
        $this->{$method}();
        Log::info($method . "[$this->level]", ['do' => $this->do, 'uid' => $this->uid, 'brandId' => $this->brandId, 'work' => $this->work, 'taskId' => $this->taskId, 'growth' => $this->growth]);
        if (!empty($this->taskId) && $this->do) {
            if (is_scalar($this->taskId)) $this->taskId = [$this->taskId];
            foreach ($this->taskId as $v) {
                Task::handleTask($this->uid, $v);
            }
        }
    }

    public static function __callStatic($name, $arguments)
    {
        $uid = $arguments[0] ?? 0;
        $brandId = $arguments[1] ?? 0;
        $increase = $arguments[2] ?? true;
        if ($uid == 0 && $brandId == 0) return false;
        foreach (['levelTask', 'dailyTask', 'primaryTask'] as $method) {
            if (strstr($name, $method)) {
                $work = str_replace($method, '', $name);
                self::getInstance($uid, $brandId)->increaseAble($increase)->brandInfo()->setWork(lcfirst($work))->run($method);
                break;
            }
        }

    }

}